home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianPreferences.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  20KB  |  662 lines

  1. /*ScianPreferences.c
  2.   Eric Pepke
  3.   June 15, 1991
  4.   Preferences in SciAn
  5. */
  6.  
  7. #include "Scian.h"
  8. #include "ScianTypes.h"
  9. #include "ScianMethods.h"
  10. #include "ScianLists.h"
  11. #include "ScianIDs.h"
  12. #include "ScianStyle.h"
  13. #include "ScianWindows.h"
  14. #include "ScianObjWindows.h"
  15. #include "ScianDialogs.h"
  16. #include "ScianControls.h"
  17. #include "ScianButtons.h"
  18. #include "ScianTextBoxes.h"
  19. #include "ScianErrors.h"
  20. #include "ScianPreferences.h"
  21. #include "ScianScripts.h"
  22.  
  23. typedef union pv
  24.     {
  25.         char *string;        /*String value*/
  26.         Bool truth;            /*Expression true or false*/
  27.         long integer;        /*Numeric value*/
  28.     } PrefValue;
  29.  
  30. typedef struct
  31.     {
  32.     char *shortName;        /*Short name of the preference*/
  33.     char *longName;            /*Long name of the preference*/
  34.     int type;            /*Type of the preference*/
  35.     char *helpString;        /*String of the help*/
  36.     } PrefInfo;
  37.  
  38. typedef struct
  39.     {
  40.     Bool exists;            /*True iff the preference exists*/
  41.     Bool changed;            /*True iff the preference has been changed*/
  42.     PrefValue value;        /*Value of the preference*/
  43.     } PrefState;
  44.  
  45. PrefInfo prefInfo[NPREFERENCES] =
  46.     {
  47.     {"DEFDIR", "Data File Directory", PT_STRING,
  48. "This controls the default directory that will be used when you choose NewFileWindow from the File menu.  \
  49. Edit the string in the text box to change it."},
  50.     {"ROTINERTIA", "Rotation Inertia", PT_YNBOOL,
  51. "This controls the inertia when you rotate objects within a space.  \
  52. If Yes is selected, the space will continue to rotate it when you give it a spin and release the mouse button while moving the mouse.  \
  53. You can stop the rotation by clicking in the space again."},
  54.     {"NEWWINPLACE", "New Window Placement", PT_AMBOOL,
  55. "This controls how new windows will be placed on the screen.  If Automatic is \
  56. selected, windows will be created with a fixed size and automatically staggered.  \
  57. If Manual is selected, you will need to drag out the outline of new windows \
  58. before they appear on the screen."},
  59.     {"DRAWMOVING", "Interactive Drawing", PT_AFFINT,
  60. "This controls how visualization objects are drawn when you are interactively \
  61. changing them.  If Full Quality is selected, objects will always be drawn in full \
  62. quality.  If Faster is selected, objects will be drawn with only a skeleton while you are \
  63. interactively moving them, which is much faster.  This can provide better feedback \
  64. on slower computers.  If Automatic is selected, SciAn will automatically choose whether \
  65. objects are to be drawn fully or faster depending on how much time they take to draw."},
  66.     {"STAGGERICONS", "Stagger Icons", PT_YNBOOL,
  67. "This controls whether icons will be staggered in icon corrals.  If Yes is selected, \
  68. the vertical position of the icons will be staggered so that long icon names have \
  69. less chance of overlapping.  If No is selected, icons will not be staggered."}
  70.     ,
  71.     {"SCREENSAVE", "Screen Save", PT_RPINT,
  72. "This controls whether screen snapshots are saved as IRIS rgb files or as PostScript files.  \
  73. If PostScript is selected they will be saved as embedded PostScript files with a file extension \
  74. of .eps.  If IRIS RGB is selected, they will be saved as IRIS RGB files with a file \
  75. extension of .rgb.  Screen saving is done using the recorder drivers, and the \
  76. parameters are set within the recorder driver control panels."},
  77.     {"IDLENAP", "Nap When Idle", PT_YNBOOL,
  78. "This controls whether SciAn naps when it is idle.  When No is checked, SciAn will \
  79. constantly run housekeeping functions.  This will ensure that interaction is quick, but \
  80. it may slow down other processes running on the computer.  When Yes is checked, SciAn will \
  81. nap for one-second intervals five seconds after the last window change.  This will \
  82. release time for use by other processes, but the first interaction when it is napping \
  83. may take up to a second to respond."},
  84.     {"GARBAGECOLLECT", "Garbage Collection", PT_SFBOOL,
  85. "This controls whether garbage collection is absolutely safe or a little bit \
  86. faster."}
  87.     };
  88.  
  89. PrefState prefState[NPREFERENCES];
  90.  
  91. #define PREFCELLHEIGHT    40        /*Height of a cell in preferences*/
  92. #define PREFNAMEWIDTH    200        /*Width of the name of a preference*/
  93. #define PREFFIELDWIDTH    400        /*Width of a field of a preference*/
  94.  
  95. Bool PrefExists(whichPref)
  96. int whichPref;
  97. /*Returns true iff whichPref exists*/
  98. {
  99.     return prefState[whichPref] . exists;
  100. }
  101.  
  102. char *GetPrefString(whichPref)
  103. int whichPref;
  104. /*Gets the string for preference whichPref*/
  105. {
  106.     if (prefInfo[whichPref] . type != PT_STRING) return 0;
  107.     return prefState[whichPref] . value . string;
  108. }
  109.  
  110. Bool GetPrefTruth(whichPref)
  111. int whichPref;
  112. /*Gets the truth for preference whichPref*/
  113. {
  114.     if (prefInfo[whichPref] . type != PT_YNBOOL &&
  115.     prefInfo[whichPref] . type != PT_AMBOOL &&
  116.     prefInfo[whichPref] . type != PT_SFBOOL)
  117.     {
  118.     return false;
  119.     }
  120.     return prefState[whichPref] . value . truth;
  121. }
  122.  
  123. long GetPrefInteger(whichPref)
  124. int whichPref;
  125. /*Gets the integer for preference whichPref*/
  126. {
  127.     if (prefInfo[whichPref] . type != PT_AFFINT &&
  128.     prefInfo[whichPref] . type != PT_RPINT)
  129.     {
  130.     return false;
  131.     }
  132.     return prefState[whichPref] . value . integer;
  133. }
  134.  
  135. static void MakePrefFromString(whichPref, string)
  136. int whichPref;
  137. char *string;
  138. /*Makes a preference whichPref from string*/
  139. {
  140.     prefState[whichPref] . exists = true;
  141.     switch(prefInfo[whichPref] . type)
  142.     {
  143.     case PT_STRING:
  144.         prefState[whichPref] . value . string = Alloc(strlen(string) + 1);
  145.         strcpy(prefState[whichPref] . value . string, string);
  146.         break;
  147.     case PT_YNBOOL:
  148.         if (strcmp2(string, "yes") == 0 || strcmp2(string, "true") == 0)
  149.         {
  150.         prefState[whichPref] . value . truth = true;
  151.         }
  152.         else
  153.         {
  154.         prefState[whichPref] . value . truth = false;
  155.         }
  156.         break;
  157.     case PT_AMBOOL:
  158.         if (strcmp2(string, "auto") == 0 || strcmp2(string, "automatic") == 0)
  159.         {
  160.         prefState[whichPref] . value . truth = true;
  161.         }
  162.         else
  163.         {
  164.         prefState[whichPref] . value . truth = false;
  165.         }
  166.         break;
  167.     case PT_SFBOOL:
  168.         if (strcmp2(string, "fast") == 0 || strcmp2(string, "reckless") == 0)
  169.         {
  170.         prefState[whichPref] . value . truth = true;
  171.         }
  172.         else
  173.         {
  174.         prefState[whichPref] . value . truth = false;
  175.         }
  176.         break;
  177.     case PT_AFFINT:
  178.         if (strcmp2(string, "auto") == 0 || strcmp2(string, "automatic") == 0)
  179.         {
  180.         prefState[whichPref] . value . integer = 2;
  181.         }
  182.         else if (strcmp2(string, "fast") == 0 || strcmp2(string, "faster") == 0)
  183.         {
  184.         prefState[whichPref] . value . integer = 1;
  185.         }
  186.         else
  187.         {
  188.         prefState[whichPref] . value . integer = 0;
  189.         }
  190.         break;
  191.     case PT_RPINT:
  192.         if (strcmp2(string, "post") == 0 || strcmp2(string, "postscript") == 0)
  193.         {
  194.         prefState[whichPref] . value . integer = 1;
  195.         }
  196.         else
  197.         {
  198.         prefState[whichPref] . value . integer = 0;
  199.         }
  200.         break;
  201.     }
  202. }
  203.  
  204. static ObjPtr ChangePrefString(object)
  205. ObjPtr object;
  206. /*Changed value for a text box object that controls a string preference*/
  207. {
  208.     ObjPtr var, value;
  209.     int whichPref;
  210.  
  211.     var = GetIntVar("ChangePrefString", object, WHICHPREF);
  212.     if (!var)
  213.     {
  214.     return ObjFalse;
  215.     }
  216.     whichPref = GetInt(var);
  217.  
  218.     value = GetValue(object);
  219.     if (!value || !IsString(value))
  220.     {
  221.     return ObjFalse;
  222.     }
  223.  
  224.     if (prefState[whichPref] . value . string)
  225.     {
  226.     Free(prefState[whichPref] . value . string);
  227.     }
  228.     prefState[whichPref] . value . string = Alloc(strlen(GetString(value)) + 1);
  229.     strcpy(prefState[whichPref] . value . string, GetString(value));
  230.     prefState[whichPref] . changed = true;
  231.     prefState[whichPref] . exists = true;
  232.  
  233.     return ObjTrue;
  234. }
  235.  
  236. static ObjPtr ChangePrefBoolean(object)
  237. ObjPtr object;
  238. /*Changed value for a text box object that controls a boolean preference*/
  239. {
  240.     ObjPtr var, value;
  241.     int whichPref;
  242.  
  243.     var = GetIntVar("ChangePrefBoolean", object, WHICHPREF);
  244.     if (!var)
  245.     {
  246.     return ObjFalse;
  247.     }
  248.     whichPref = GetInt(var);
  249.  
  250.     value = GetValue(object);
  251.     if (!value || !IsInt(value))
  252.     {
  253.     return ObjFalse;
  254.     }
  255.  
  256.     prefState[whichPref] . value . truth = GetInt(value);
  257.     prefState[whichPref] . changed = true;
  258.     prefState[whichPref] . exists = true;
  259.  
  260.     return ObjTrue;
  261. }
  262.  
  263. static ObjPtr ChangePrefInteger(object)
  264. ObjPtr object;
  265. /*Changed value for a text box object that controls an integer preference*/
  266. {
  267.     ObjPtr var, value;
  268.     int whichPref;
  269.  
  270.     var = GetIntVar("ChangePrefInteger", object, WHICHPREF);
  271.     if (!var)
  272.     {
  273.     return ObjFalse;
  274.     }
  275.     whichPref = GetInt(var);
  276.  
  277.     value = GetValue(object);
  278.     if (!value || !IsInt(value))
  279.     {
  280.     return ObjFalse;
  281.     }
  282.  
  283.     prefState[whichPref] . value . integer = GetInt(value);
  284.     prefState[whichPref] . changed = true;
  285.     prefState[whichPref] . exists = true;
  286.     return ObjTrue;
  287. }
  288.  
  289. void DoShowPreferences()
  290. /*Shows the preferences dialog*/
  291. {
  292.     WinInfoPtr dialogExists, newDialog;
  293.     ObjPtr whichDialog;
  294.     int nPreferences;
  295.  
  296.     if (logging)
  297.     {
  298.     Log("show preferences\n");
  299.     InhibitLogging(true);
  300.     }
  301.     
  302.     whichDialog = NewString("Preferences");
  303.  
  304. #ifdef RELEASE
  305.     nPreferences = NRELEASEPREFERENCES;
  306. #else
  307.     nPreferences = NPREFERENCES;
  308. #endif
  309.  
  310.     dialogExists = DialogExists(0, whichDialog);
  311.     newDialog = GetDialog(0, whichDialog, "Preferences",
  312.     PREFNAMEWIDTH + PREFFIELDWIDTH + 3 * MAJORBORDER,
  313.     PREFCELLHEIGHT * nPreferences + MAJORBORDER * 2,
  314.     PREFNAMEWIDTH + PREFFIELDWIDTH + 3 * MAJORBORDER,
  315.     PREFCELLHEIGHT * nPreferences + MAJORBORDER * 2,
  316.     WINUI + WINFIXEDSIZE);
  317.  
  318.     if (!dialogExists)
  319.     {
  320.     /*Fill the dialog with stuff*/
  321.     ObjPtr contents, panel, radio, button, textBox;
  322.     int left, right, bottom, top;
  323.     int k;
  324.  
  325.     /*Set the help string*/
  326.     SetVar((ObjPtr) newDialog, HELPSTRING,
  327.         NewString("This window shows your personal preferences for using \
  328. SciAn.  The preferences are saved in a file named \".scianPrefs\" in your home \
  329. directory when you exit SciAn normally.  \
  330. Use Help In Context and click on the various controls to find out what they do."));
  331.  
  332.     contents = GetListVar("DoShowPreferences", (ObjPtr) newDialog, CONTENTS);
  333.     if (!contents) return;
  334.     panel = NewPanel(greyPanelClass, 
  335.         0, PREFNAMEWIDTH + PREFFIELDWIDTH + 3 * MAJORBORDER,
  336.         0, PREFCELLHEIGHT * nPreferences + MAJORBORDER * 2
  337.         );
  338.     if (!panel)
  339.     {
  340.         return;
  341.     }
  342.     PrefixList(contents, panel);
  343.     contents = GetListVar("DoShowPreferences", panel, CONTENTS);
  344.     if (!contents) return;
  345.     SetVar(panel, PARENT, (ObjPtr) newDialog);
  346.  
  347.     for (k = 0; k < nPreferences; ++k)
  348.     {
  349.         char objName[200], longName[300];
  350.         int median;
  351.  
  352.         /*Calculate a median line*/
  353.         median = MAJORBORDER + PREFCELLHEIGHT / 2 + PREFCELLHEIGHT * (nPreferences - 1 - k);
  354.  
  355.         /*Add a text box for this preference*/
  356.         sprintf(objName, "%s name", prefInfo[k] . shortName);
  357.         if (prefInfo[k] . type == PT_YNBOOL)
  358.         {
  359.         sprintf(longName, "%s?", prefInfo[k] . longName);
  360.         }
  361.         else
  362.         {
  363.         sprintf(longName, "%s:", prefInfo[k] . longName);
  364.         }
  365.         textBox = NewTextBox(MAJORBORDER, MAJORBORDER + PREFNAMEWIDTH,
  366.                  median - TEXTBOXHEIGHT / 2, median + TEXTBOXHEIGHT / 2,
  367.                  0, objName, longName);
  368.         PrefixList(contents, textBox);
  369.         SetVar(textBox, PARENT, panel);
  370.         SetVar(textBox, HELPSTRING, NewString(prefInfo[k] . helpString));
  371.         SetTextFont(textBox, "Helvetica-Bold");
  372.  
  373.         /*Add the field based on the type of preference*/
  374.         switch(prefInfo[k] . type)
  375.         {
  376.         case PT_STRING:
  377.             sprintf(objName, "%s field", prefInfo[k] . shortName);
  378.             textBox = NewTextBox(
  379.             MAJORBORDER * 2 + PREFNAMEWIDTH,
  380.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH,
  381.             median - PITBOXHEIGHT / 2, median + PITBOXHEIGHT / 2,
  382.             EDITABLE + WITH_PIT + ONE_LINE, objName,
  383.             prefState[k] . value . string);
  384.             PrefixList(contents, textBox);
  385.             SetVar(textBox, HELPSTRING, NewString(prefInfo[k] . helpString));
  386.              SetVar(textBox, PARENT, panel);
  387.             SetVar(textBox, WHICHPREF, NewInt(k));
  388.             SetMethod(textBox, CHANGEDVALUE, ChangePrefString);
  389.             break;
  390.         case PT_YNBOOL:
  391.             sprintf(objName, "%s radio", prefInfo[k] . shortName);
  392.             radio = NewRadioButtonGroup(objName);
  393.             PrefixList(contents, radio);
  394.             SetVar(radio, PARENT, panel);
  395.             SetVar(radio, HELPSTRING, NewString(prefInfo[k] . helpString));
  396.  
  397.             button = NewRadioButton(
  398.             MAJORBORDER * 2 + PREFNAMEWIDTH,
  399.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  400.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  401.             "No");
  402.             AddRadioButton(radio, button);
  403.  
  404.             button = NewRadioButton(
  405.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  406.             MAJORBORDER * 2 + PREFNAMEWIDTH + 2 * PREFFIELDWIDTH / 3,
  407.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  408.             "Yes");
  409.             AddRadioButton(radio, button);
  410.             SetValue(radio, NewInt(prefState[k] . value . truth));
  411.             SetVar(radio, WHICHPREF, NewInt(k));
  412.             SetMethod(radio, CHANGEDVALUE, ChangePrefBoolean);
  413.             break;
  414.         case PT_AMBOOL:
  415.             sprintf(objName, "%s radio", prefInfo[k] . shortName);
  416.             radio = NewRadioButtonGroup(objName);
  417.             PrefixList(contents, radio);
  418.             SetVar(radio, PARENT, panel);
  419.             SetVar(radio, HELPSTRING, NewString(prefInfo[k] . helpString));
  420.  
  421.             button = NewRadioButton(
  422.             MAJORBORDER * 2 + PREFNAMEWIDTH,
  423.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  424.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  425.             "Manual");
  426.             AddRadioButton(radio, button);
  427.  
  428.             button = NewRadioButton(
  429.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  430.             MAJORBORDER * 2 + PREFNAMEWIDTH + 2 * PREFFIELDWIDTH / 3,
  431.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  432.             "Automatic");
  433.             AddRadioButton(radio, button);
  434.             SetValue(radio, NewInt(prefState[k] . value . truth));
  435.             SetVar(radio, WHICHPREF, NewInt(k));
  436.             SetMethod(radio, CHANGEDVALUE, ChangePrefBoolean);
  437.             break;
  438.         case PT_SFBOOL:
  439.             sprintf(objName, "%s radio", prefInfo[k] . shortName);
  440.             radio = NewRadioButtonGroup(objName);
  441.             PrefixList(contents, radio);
  442.             SetVar(radio, PARENT, panel);
  443.             SetVar(radio, HELPSTRING, NewString(prefInfo[k] . helpString));
  444.  
  445.             button = NewRadioButton(
  446.             MAJORBORDER * 2 + PREFNAMEWIDTH,
  447.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  448.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  449.             "Safer");
  450.             AddRadioButton(radio, button);
  451.  
  452.             button = NewRadioButton(
  453.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  454.             MAJORBORDER * 2 + PREFNAMEWIDTH + 2 * PREFFIELDWIDTH / 3,
  455.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  456.             "Faster");
  457.             AddRadioButton(radio, button);
  458.             SetValue(radio, NewInt(prefState[k] . value . truth));
  459.             SetVar(radio, WHICHPREF, NewInt(k));
  460.             SetMethod(radio, CHANGEDVALUE, ChangePrefBoolean);
  461.             break;
  462.         case PT_AFFINT:
  463.             sprintf(objName, "%s radio", prefInfo[k] . shortName);
  464.             radio = NewRadioButtonGroup(objName);
  465.             PrefixList(contents, radio);
  466.             SetVar(radio, PARENT, panel);
  467.             SetVar(radio, HELPSTRING, NewString(prefInfo[k] . helpString));
  468.  
  469.             button = NewRadioButton(
  470.             MAJORBORDER * 2 + PREFNAMEWIDTH,
  471.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  472.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  473.             "Full Quality");
  474.             AddRadioButton(radio, button);
  475.  
  476.             button = NewRadioButton(
  477.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  478.             MAJORBORDER * 2 + PREFNAMEWIDTH + 2 * PREFFIELDWIDTH / 3,
  479.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  480.             "Faster");
  481.             AddRadioButton(radio, button);
  482.  
  483.             button = NewRadioButton(
  484.             MAJORBORDER * 2 + PREFNAMEWIDTH + 2 * PREFFIELDWIDTH / 3,
  485.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH,
  486.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  487.             "Automatic");
  488.             AddRadioButton(radio, button);
  489.  
  490.             SetValue(radio, NewInt(prefState[k] . value . integer));
  491.             SetVar(radio, WHICHPREF, NewInt(k));
  492.             SetMethod(radio, CHANGEDVALUE, ChangePrefInteger);
  493.             break;
  494.         case PT_RPINT:
  495.             sprintf(objName, "%s radio", prefInfo[k] . shortName);
  496.             radio = NewRadioButtonGroup(objName);
  497.             PrefixList(contents, radio);
  498.             SetVar(radio, PARENT, panel);
  499.             SetVar(radio, HELPSTRING, NewString(prefInfo[k] . helpString));
  500.  
  501.             button = NewRadioButton(
  502.             MAJORBORDER * 2 + PREFNAMEWIDTH,
  503.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  504.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  505.             "IRIS RGB");
  506.             AddRadioButton(radio, button);
  507.  
  508.             button = NewRadioButton(
  509.             MAJORBORDER * 2 + PREFNAMEWIDTH + PREFFIELDWIDTH / 3,
  510.             MAJORBORDER * 2 + PREFNAMEWIDTH + 2 * PREFFIELDWIDTH / 3,
  511.             median - CHECKBOXHEIGHT / 2, median + CHECKBOXHEIGHT / 2,
  512.             "PostScript");
  513.             AddRadioButton(radio, button);
  514.  
  515.             SetValue(radio, NewInt(prefState[k] . value . integer));
  516.             SetVar(radio, WHICHPREF, NewInt(k));
  517.             SetMethod(radio, CHANGEDVALUE, ChangePrefInteger);
  518.             break;
  519.         }
  520.     }
  521.     }
  522.  
  523.     if (logging)
  524.     {
  525.     InhibitLogging(false);
  526.     }
  527. }
  528.  
  529. void InitPreferences()
  530. /*Initialize the preferences*/
  531. {
  532.     int k;
  533.     FILE *prefFile;
  534.  
  535.     /*Avoid a core dump if I forget to handle all preferences*/
  536.     for (k = 0; k < NPREFERENCES; ++k)
  537.     {
  538.     prefState[k] . value . string = 0;
  539.     prefState[k] . changed = false;
  540.     }
  541.  
  542.     /*Set up default values for all preferences*/
  543.     prefState[PREF_DEFDIR] . value . string = Alloc(2);
  544.     strcpy(prefState[PREF_DEFDIR] . value . string, ".");
  545.     prefState[PREF_ROTINERTIA] . value . truth = true;
  546.     prefState[PREF_NEWWINPLACE] . value . truth = true;
  547.     prefState[PREF_DRAWMOVING] . value . integer = DM_FULL;
  548.  
  549.     /*Try to read all preferences from environment variables*/
  550.     for (k = 0; k < NPREFERENCES; ++k)
  551.     {
  552.     char *envString;
  553.     prefState[k] . exists = false;
  554.  
  555.     /*See if it can be read from an environment variable*/
  556.     strcpy(tempStr, "SCIAN_");
  557.     strcat(tempStr, prefInfo[k] . shortName);
  558.     envString = getenv(tempStr);
  559.     if (envString)
  560.     {
  561.         MakePrefFromString(k, envString);
  562.     }
  563.     }
  564.  
  565.     /*If a preferences file exists, open it and read it*/
  566.     sprintf(tempStr, "%s/%s", getenv("HOME"), ".scianPrefs");
  567.     prefFile = fopen(tempStr, "r");
  568.     if (prefFile)
  569.     {
  570.     char *s1, *s2, *s3;
  571.     while (fgets(tempStr, TEMPSTRSIZE, prefFile))
  572.     {
  573.         s1 = tempStr;
  574.         while (*s1 && *s1 == ' ') ++s1;
  575.         s2 = s1;
  576.         while (*s2 && *s2 != ' ') ++s2;
  577.         *s2++ = 0;
  578.         while (*s2 && *s2 == ' ') ++s2;
  579.         s3 = s2;
  580.         while (*s3 && *s3 != '\n') ++s3;
  581.         *s3 = 0;
  582.  
  583.         for (k = 0; k < NPREFERENCES; ++k)
  584.         {
  585.         if (0 == strcmp2(s1, prefInfo[k] . shortName))
  586.         {
  587.             MakePrefFromString(k, s2);
  588.             break;
  589.         }
  590.         }
  591.     }
  592.     fclose(prefFile);
  593.     }
  594. }
  595.  
  596. void KillPreferences()
  597. /*Kills the preferences*/
  598. {
  599.     int k;
  600.     Bool savePreferences;
  601.  
  602.     savePreferences = false;
  603.     /*Determine if preferences should be saved*/
  604.     for (k = 0; k < NPREFERENCES; ++k)
  605.     {
  606.     if (prefState[k] . changed)
  607.     {
  608.         savePreferences = true;
  609.     }
  610.     }
  611.  
  612.     if (savePreferences)
  613.     {
  614.     /*Save the preferences*/
  615.     FILE *prefFile;
  616.     sprintf(tempStr, "%s/%s", getenv("HOME"), ".scianPrefs");
  617.     prefFile = fopen(tempStr, "w");
  618.     if (prefFile)
  619.     {
  620.         for (k = 0; k < NPREFERENCES; ++k)
  621.         {
  622.         if (prefState[k] . exists)
  623.         {
  624.             fprintf(prefFile, "%s ", prefInfo[k] . shortName);
  625.             switch (prefInfo[k] . type)
  626.             {
  627.             case PT_STRING:
  628.                 fprintf(prefFile, "%s\n", prefState[k] . value . string);
  629.                 break;
  630.             case PT_YNBOOL:
  631.                 fprintf(prefFile, "%s\n", prefState[k] . value . truth ? "yes" : "no");
  632.                 break;
  633.             case PT_AMBOOL:
  634.                 fprintf(prefFile, "%s\n", prefState[k] . value . truth ? "auto" : "manual");
  635.                 break;
  636.             case PT_SFBOOL:
  637.                 fprintf(prefFile, "%s\n", prefState[k] . value . truth ? "fast" : "safe");
  638.                 break;
  639.             case PT_AFFINT:
  640.                 fprintf(prefFile, "%s\n", prefState[k] . value . integer ? (prefState[k] . value . integer == 2 ? "auto" : "faster") : "full");
  641.                 break;
  642.             case PT_RPINT:
  643.                 fprintf(prefFile, "%s\n", prefState[k] . value . integer ? "PostScript" : "RGB");
  644.                 break;
  645.             }
  646.         }
  647.         }
  648.         fclose(prefFile);
  649.     }
  650.     }
  651.  
  652.     /*Get rid of the preferences*/
  653.     for (k = 0; k < NPREFERENCES; ++k)
  654.     {
  655.     if ((prefInfo[k] . type == PT_STRING) && (prefState[k] . value . string))
  656.     {
  657.         Free(prefState[k] . value . string);
  658.         prefState[k] . value . string = 0;
  659.     }
  660.     }
  661. }
  662.